/**
* Switches the resource grid between fullscreen/condensed
* @param linkButton A DOM object of the link which changes the view
*/
function toggleFullWindow(linkButton) {
    var fullsizeDiv = document.getElementById(GetClientId("fullsizeholder"));
    if (typeof (fullsizeDiv) != "undefined") {
        if (fullsizeDiv.className.toLowerCase() == "ssfullsize") {
            fullsizeDiv.className = "ssContracted";
            linkButton.className = "lnkExpand";
            linkButton.childNodes[0].nodeValue = "Expand to fill window";
        } else {
            fullsizeDiv.className = "ssFullSize";
            linkButton.className = "lnkContract";
            linkButton.childNodes[0].nodeValue = "Contract to normal size";
        }
    }
    return false;
}

/**
* Returns a JSON request string for use when requesting translations for a resource
* @param textBoxId The ID of the textbox containing the resource to find
* @param requestLanguage The language of the text in the textbox ( language-COUNTRY )
* @param offset The index of the first record to return
*/
function getResourceData(textBoxId, requestLanguage, offset) {
    var request = { type: "request", language: requestLanguage, translation: encodeURI(document.getElementById(textBoxId).value), offset: offset };
    return $.toJSON(request);
}

/**
* Selects a resource when a list item is clicked
* @param selectedResource The ID of the resource which was selected
* @param tableCell The ID of the cell containing the results div
* @param addResource True if this textbox is located on the add resource form (table structure is different)
*/
function selectResource(selectedResource, tableCell, addResource) {
    var cbo;
    if (addResource) {
        cbo = $("#" + GetClientId("cboAddResourceId"));
    } else {
        var parent = $("#" + tableCell).parent();
        cbo = parent.find("td:eq(3) select");
    }
    cbo.find("option").removeAttr("selected");
    cbo.find("option[value=" + selectedResource + "]").attr("selected", "selected");
    cbo.change();
}

/**
* Used by the resource finder ('borrowed' from JQuery's autocompleter ;)
*/
function target(event, parentTag) {
    var element = event.target;
    while (element && element.tagName != parentTag) {
        element = element.parentNode;
    }
    if (!element) { // IE fix
        return [];
    }
    return element;
}

/**
* AJAX callback which shows a list of translations for the resource in the specified cell/div (determined by the tagName of the element)
* @param jsonResponse The JSON response received from the server
* @param containerCell The ID of the <td> element containing the textbox
* @param addResource True if this textbox is located on the add resource form (table structure is different)
*/
function showMatchingResources(jsonResponse, containerCell, addResource) {
    var response = $.evalJSON(jsonResponse).d;
    var resourceIds = response.resources;
    var numberFound = response.found;
    var active = -1;
    var parentCell = $("#" + containerCell);
    parentCell.find(".ajax").addClass('ajax-small'); // re-hide
    parentCell.find("#ajax-" + containerCell).remove();
    parentCell.find("#loading-" + containerCell).remove();
    var element = $("<div/>")
        .addClass("find_results")
        .attr("id", "ajax-" + containerCell)
        .mouseover(function(event) {
            var realTarget = target(event, "LI");
            if (realTarget.nodeName && realTarget.nodeName.toUpperCase() == 'LI') {
                active = $("li", list).removeClass("find_over").index(realTarget);
                $(realTarget).addClass("find_over");
            }
        })
        .appendTo(parentCell);
    if (numberFound > 0) {
        var closeDiv = $('<div/>').addClass('find_close')
            .appendTo(element);
        var closeButton = $('<a/>')
            .attr('title', 'Close')
            .attr('href', '#')
            .text('Close')
            .click(function() {
                element.remove();
                return false;
            })
            .appendTo(closeDiv);
        var txtBox;
        if (addResource) {
            txtBox = parentCell.parent().find("td:eq(1) textarea");
        } else {
            txtBox = parentCell.find("textarea");
        }
        txtBox.keyup(function(event) {
            if (event.keyCode == 27) { // ESC
                $("#" + containerCell + "results").remove();
            }
        })
        .focus();
        if (!$.browser.msie) {
            txtBox.bind("focus", function() {
                $("#" + containerCell + "results").remove();
            });
        }
        var list = $("<ul/>")
            .addClass("find_ids");
        if (addResource) {
            var btnOffset = parentCell.find('.findResource').offset();
            element.css({
                position: "absolute",
                top: btnOffset.top,
                left: btnOffset.left + 24
            });
        } else {
            var txtOffset = txtBox.offset();
            element.css({
                position: "absolute",
                top: txtOffset.top + txtBox.height() + 32,
                left: txtOffset.left
            });
        }
        var result, i;
        for (i = 0; i < resourceIds.length; i++) {
            result = resourceIds[i];
            var li = $("<li/>")
                .attr("value", decodeURI(result.ID))
                .data("title", unescape(decodeURI(result.Comment)).replace(/\+/g, " "))
                .html(unescape(decodeURI(result.Text)).replace(/\+/g, " "))
                .addClass(i % 2 === 0 ? "find_even" : "find_odd")
                .click(function(event) {
                    $(target(event), "LI").addClass("find_active");
                    $("#" + containerCell + "results").remove();
                    selectResource($(this).attr("value"), containerCell, addResource);
                }).mouseout(function() {
                    $(this).removeClass("find_over");
                })
                .appendTo(list)[0];
        }
        list.appendTo(element);
        var perPage = response.perpage;
        var offset = response.offset; // the current offset
        var numPages = Math.ceil(numberFound / perPage);
        var currentPage = (offset / perPage) + 1;
        if (numPages > 1) {
            var txtBoxId = txtBox[0].id;
            var pages = $("<ul/>")
                .addClass("pages")
                .attr("id", containerCell + "pages")
                .appendTo(element);
            var firstPage = $("<li/>") // always show the first page
                .appendTo(pages);
            if (currentPage === 1) {
                firstPage.addClass("currentPage")
                    .text("1");
            } else {
                var firstLink = $("<a/>")
                    .text("1")
                    .appendTo(firstPage);
                addFindSimilarPageListener(firstLink, containerCell, addResource, response.language, txtBoxId, 0);
            }
            if (numPages > 2) {
                var firstInterimPage, lastInterimPage;
                if (currentPage <= 4) {
                    firstInterimPage = 2;
                } else if (currentPage >= numPages - 2) {
                    firstInterimPage = numPages - 3;
                } else {
                    firstInterimPage = currentPage - 1;
                }
                if (currentPage < 3) {
                    lastInterimPage = Math.min(numPages - 1, 4);
                } else if (currentPage > numPages - 2) {
                    lastInterimPage = numPages - 1;
                } else {
                    lastInterimPage = currentPage + 1;
                }
                if (firstInterimPage > 2) {
                    var firstSpacer = $("<li/>")
                        .text("...")
                        .addClass("spacer")
                        .appendTo(pages);
                }
                for (i = firstInterimPage; i <= lastInterimPage; i++) {
                    var pg = $("<li/>")
                        .appendTo(pages);
                    if (i === currentPage) {
                        pg.text(i);
                    } else {
                        var pgLink = $("<a/>")
                            .text(i)
                            .appendTo(pg);
                        addFindSimilarPageListener(pgLink, containerCell, addResource, response.language, txtBoxId, (perPage * i) - perPage);
                    }
                }
                if (lastInterimPage < numPages - 1) {
                    var lastSpacer = $("<li/>")
                        .text("...")
                        .addClass("spacer")
                        .appendTo(pages);
                }
            }
            var lastPage = $("<li/>") // always show the last page
                .appendTo(pages);
            if (currentPage === numPages) {
                lastPage.addClass("currentPage")
                    .text(numPages);
            } else {
                var lastLink = $("<a/>")
                    .text(numPages)
                    .appendTo(lastPage);
                addFindSimilarPageListener(lastLink, containerCell, addResource, response.language, txtBoxId, (perPage * numPages) - perPage);
            }
        }
    } else {
        element.html("<p>No similar translations</p>")
               .fadeOut(4000);
    }
}

/**
* Adds a listener to find more resources
* @param jQElement The link element to which to add the listener
* @param containerCell The ID of the <td> element containing the textbox
* @param addResource True if this textbox is located on the add resource form (table structure is different)
* @param languageCode The language of the textbox
* @param txtBoxId The ID of the text box containing the translation
* @param offset The offset from which to search for more results
*/
function addFindSimilarPageListener(jQElement, containerCell, addResource, languageCode, txtBoxId, offset) {
    jQElement.click(function() {
        var parentCell = $("#" + containerCell);
        var divParent = jQElement.parents(".find_results");
        var elementOffset = divParent.offset();
        var loader = $("<div/>")
            .css({ position: "absolute",
                top: elementOffset.top,
                left: elementOffset.left,
                width: divParent.width(),
                height: divParent.height()
            })
            .addClass("loadingDiv")
            .attr("id", "loading-" + containerCell)
            .appendTo(parentCell);
        var loadingImg = $("<img/>")
            .attr("src", "./images/ajax-small.gif")
            .appendTo(loader);
        $.ajax({ type: "POST", url: "ResourceFinder.asmx/FindResource", contentType: "application/json; charset=utf-8", data: getResourceData(txtBoxId, languageCode, offset), success: function(response) {
            showMatchingResources(response, containerCell, addResource);
        }
        }); return false;
    });
}

/**
* Adds a listener to find similar translations
* @param buttonId The ID of the button to which to assign the listener
* @param txtBoxId The ID of the text box containing the translation
* @param containerCell The ID of the <td> element containing the textbox
* @param languageCode The language of the textbox
* @param addResource True if this textbox is located on the add resource form (table structure is different)
*/
function addFindSimilarListener(buttonId, txtBoxId, containerCell, languageCode, addResource) {
    var btn = $("#" + buttonId);
    btn.unbind();
    btn.click(function() {
        var container = $("#" + containerCell);
        container.find(".ajax-small").removeClass("ajax-small");
        $.ajax({ type: "POST", url: "ResourceFinder.asmx/FindResource", contentType: "application/json; charset=utf-8", data: getResourceData(txtBoxId, languageCode, 0), success: function(response) {
            showMatchingResources(response, containerCell, addResource);
        }
        }); return false;
    });
}

/**
* Adds a listener to translate with Google
* @param buttonId The ID of the button to which to assign the listener
* @param srcTextboxId The ID of the text box containing the source translation
* @param srcGoogleCode The Google code of the source language
* @param destTextboxId The ID of the text box in which to show the translation
* @param destGoogleCode The Google code of the destioation language
*/
function addGoogleTranslateListener(buttonId, srcTextboxId, srcGCode, destTextboxId, destGCode) {
    $("#" + buttonId).click(function() {
        var srcText = $.trim($('#' + srcTextboxId).val());
        if (srcText.length > 0) {
            $.ajax({ type: "POST", url: "GoogleBridge.asmx/Translate", contentType: "application/json; charset=utf-8", data: $.toJSON({ q: encodeURIComponent(srcText), langpair: srcGCode + "%7C" + destGCode }), success: function(response) {
                var resp = $.evalJSON($.evalJSON(response).d);
                if (resp.responseStatus !== 200) {
                    alert("Error " + resp.responseStatus + ": " + resp.responseDetails);
                } else {
                    $('#' + destTextboxId).val(resp.responseData.translatedText);
                }
            }
            }); return false;
        } else {
            $.unblockUI();
            alert("The default language is blank");
        }
    });
}

function editPO(txtBoxId) {
    var txtBox = $('#' + txtBoxId);
    var txtBoxOffset = txtBox.offset();
    var div = $('#poedit');
    var btnSave = div.find('.btnSave'),
        btnCancel = div.find('.btnCancel'),
        txtSrcComments = $('#txtSrcComments'),
        txtReferences = $('#txtReferences'),
        txtFlags = $('#txtFlags'),
        txtContext = $('#txtContext');
    var closeLinks = { a: btnCancel, b: div.find('.btnClose') };
    $.each(closeLinks, function(blah, element) {
        element.unbind();
        element.click(function(e) {
            e.preventDefault();
            div.fadeOut();
            return false;
        });
    });
    btnSave.unbind();
    btnSave.click(function(e) {
        var srcComments = $.trim(txtSrcComments.val()).split('\n'),
            references = $.trim(txtReferences.val()).split('\n'),
            flags = $.trim(txtFlags.val()).split('\n'),
            context = $.trim(txtContext.val()),
            rawData = "",
            j = 0;
        if (srcComments.length > 0) {
            for (j = 0; j < srcComments.length; j++) {
                if (srcComments[j].length === 0) {
                    continue;
                }
                rawData += "#. " + srcComments[j] + "\n";
            }
        }
        if (references.length > 0) {
            for (j = 0; j < references.length; j++) {
                if (references[j].length === 0) {
                    continue;
                }
                rawData += "#: " + references[j] + "\n";
            }
        }
        if (flags.length > 0) {
            for (j = 0; j < flags.length; j++) {
                if (flags[j].length === 0) {
                    continue;
                }
                rawData += "#, " + flags[j] + "\n";
            }
        }
        if (context.length > 0) {
            rawData += "msgctxt " + context + "\n";
        }
        txtBox.val(rawData);
        e.preventDefault();
        div.fadeOut();
        return false;
    });
    btnCancel.unbind();
    btnCancel.click(function(e) {
        e.preventDefault();
        div.fadeOut();
        return false;
    });
    
    var metaData = {
        srcComments : "",
        references : "",
        flags : ""
    };
    var line,
        i;
    txtContext.val('');
    if(txtBox.val().length > 0) {
        var lines = txtBox.val().split('\n');
        for (i = 0; i < lines.length; i++) {
            line = lines[i];
            if(line.length < 4) {
                continue;
            }
            switch(line.substring(0, 2)) {
                case "#.":
                    metaData.srcComments += $.trim(line.substring(2))+"\n";
                    break;
                case "#:":
                    metaData.references += $.trim(line.substring(2))+"\n";
                    break;
                case "#,":
                    metaData.flags += $.trim(line.substring(2))+"\n";
                    break;
                default:
                    if (line.substring(0, 7) === "msgctxt") {
                        if (line === 'msgctxt ""') {
                            txtContext.val('""');
                        } else if (line.length >= 11) {
                            txtContext.val('"'+line.substring(9, line.length - 1)+'"');
                        }
                    }
                    break;
            }
        }
    }
    txtSrcComments.val(metaData.srcComments);
    txtReferences.val(metaData.references);
    txtFlags.val(metaData.flags);
    
    div.css({ top: txtBoxOffset.top + 10,
        left: txtBoxOffset.left + 10
    }).fadeIn();
}

/**
* Blocks the UI using jQuery. A separate function allows the trigger event to be removed.
*/
function blockFromTrigger() {
    $.blockUI({ message: $('#loadingMessage') });
}

/**
* Attaches listeners to .blockTrigger elements to block the UI.
*/
function attachBlockListeners() {
    $(".blockTrigger").unbind('click', blockFromTrigger).bind('click', blockFromTrigger);
}

/**
* Adds a new row to the bulk add form.
*/
function addBulkRow() {
    var txtHolder = $('#bulktxt')
    var formRow = $('<div/>')
                   .addClass('formrow')
                   .addClass('block')
                   .css('display','none')
                   .appendTo(txtHolder);
    var currentIndex = parseInt(txtHolder.attr('lasttxt'));  // increment the textbox index
    txtHolder.attr('lasttxt', currentIndex + 1);
    var lbl = $('<label/>')
                .attr('for', 'txtBulk' + currentIndex)
                .html("Translation " + currentIndex)
                .appendTo(formRow);
    var txt = $('<textarea/>')
               .attr('id', 'txtBulk' + currentIndex)
               .attr('name', 'txtBulk' + currentIndex)
               .attr('rows', '5')
               .attr('cols', '40')
               .addClass('wide')
               .appendTo(formRow);
    formRow.slideDown(1000);
}

/**
* Shows the 'Bulk add' form. 
* @param addForm true if the bulk add form should be positioned near the add form, false to position it at the top of the page
*/
function addBulk(addForm) {
    var div = $('#bulkadd');
    var btnCancel = $('#' + GetClientId('btnCancelBulkAdd'));
    var closeLinks = { a: btnCancel, b: div.find('.btnClose') };
    $.each(closeLinks, function(blah, element) {
        element.unbind();
        element.click(function(e) {
            e.preventDefault();
            div.fadeOut();
            return false;
        });
    });
    if (addForm) {
        div.css('top', $('#frmAdd').offset().top + 10);
    } else {
        div.css('top', 20);
    }
    div.css({ width: '85%',
              margin: '0 auto' })
       .fadeIn();
}